<template>
  <div class="video-merger">
    <div class="upload-section">
      <input type="file" multiple accept="video/*" ref="fileInput" @change="handleFileUpload">
      <div class="selected-files" v-if="selectedFiles.length">
        <p>Selected Videos:</p>
        <ul>
          <li v-for="(file, index) in selectedFiles" :key="index">
            {{ file.name || `切片视频00${index}加载中` }}
          </li>
        </ul>
      </div>
    </div>
    <div>{{ videoText[statusCode] }}</div>
    <div v-if="progress" class="progress">
      Processing: {{ progress }}%
    </div>
    <div v-if="outputUrl" class="output">
      <video controls :src="outputUrl" style="width: 600px;"></video>
      <a :href="outputUrl" download="merged-video.mp4">Download</a>
    </div>
    <button @click="mergeVideos" :disabled="isProcessing">Merge Videos</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';

const ffmpeg = new FFmpeg();
const isLoaded = ref(false);
const isProcessing = ref(false);
const selectedFiles = ref([]);
const videoText = ref(['视频加载...', '视频处理...', '视频播放']);
const statusCode = ref(0);
const progress = ref(0);
const outputUrl = ref('');
const fileInput = ref(null);
let oneFile = null;

// 初始化 FFmpeg
const load = async () => {
  try {
    // 加载 FFmpeg
    await ffmpeg.load();
    console.log('ffmpeg->', ffmpeg);
    const videourl = '/api-video/downloadFile?file_path=/opt/media/bin/www/record/xiongan/uav_63d0a6cc-55e4-4a24-898d-439aff793751/2025-01-16/08-45-07-4.mp4'
    captureVideo(`${videourl}`)
    isLoaded.value = true;
    console.log('FFmpeg loaded');
  } catch (error) {
    console.error('Failed to load FFmpeg:', error);
  }
};

// 截取视频前10秒并显示加载状态
const captureVideo = async (url) => {
  statusCode.value = 0; // 设置为加载状态
  progress.value = 0;  // 初始化进度
  console.log('视频请求地址->url->', url);
  // 更新状态为加载中
  videoText.value = ['视频加载中...', '视频处理...', '视频播放'];
  try {
    const response = await fetch(url);
    console.log('视频加载成功->', response);
    statusCode.value = 0;
    const blob = await response.blob();
    // 在视频加载和写入 FFmpeg 之间显示加载状态
    progress.value = 50;  // 更新进度，表示视频加载完成
    // 将视频文件写入 FFmpeg
    statusCode.value = 1;
    await ffmpeg.writeFile('input_video.mp4', await fetchFile(blob));
    console.log('视频已写入 FFmpeg');
    // 更新加载状态
    progress.value = 75;  // 视频已写入 FFmpeg
    // 截取前10秒的视频
    // await ffmpeg.exec(['-i', 'input_video.mp4', '-t', '10', 'output_video.mp4']);
    await ffmpeg.exec(['-ss', '00:00:00', '-i', 'input_video.mp4', '-t', '10', '-c:v', 'copy', '-c:a', 'copy', 'output_video.mp4']);
    console.log('视频前10秒已截取');
    // 获取截取的文件并生成下载链接
    const data = await ffmpeg.readFile('output_video.mp4');
    outputUrl.value = URL.createObjectURL(new Blob([data]));
    // 更新状态为完成
    statusCode.value = 2;
    progress.value = 100;  // 完成
    videoText.value = ['视频加载...', '视频处理...', '视频播放'];
  } catch (error) {
    console.error('视频处理发生错误:', error);
    // 错误处理
    statusCode.value = -1;
    videoText.value = ['加载失败，请重试！'];
  }
};

const test = async (url) => {
  // 步骤 1: 使用 fetch 加载 Blob 数据
  const response = await fetch(url);
  console.log('视频加载成功->', response);
  const blob = await response.blob();
  console.log('Blob 数据已加载->', blob);
  const arrayBuffer = await blob.arrayBuffer();
  console.log('ArrayBuffer 数据已加载->', arrayBuffer);
  const uint8Array = new Uint8Array(arrayBuffer);
  console.log('Uint8Array 数据已加载->', uint8Array);
  // 步骤 2: 使用 writeFile 写入 FFmpeg
  await ffmpeg.writeFile('video.mp4', uint8Array);
  console.log('视频已写入 FFmpeg');
  // 步骤 3: 使用 ffprobe 或 exec 处理数据
  const info = await ffmpeg.ffprobe('video.mp4');
  console.log('视频信息：', info);
}

const processVideo = async (urlArr) => {
  const towPromises = urlArr.map(itemLink => {
    console.log('视频请求地址->temLink->', itemLink);
    return fetch(itemLink, { headers: { 'Content-Type': 'video/mp4' } })
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP 错误！状态码：${response.status}`);
        }
        return response.blob();
      })
      .then(blob => {
        oneFile = new File([blob], itemLink.split('/').pop(), { type: 'video/mp4' });
        console.log('loadVideos->已加载的视频文件', oneFile);
        // 生成视频链接
        const videoUrl = URL.createObjectURL(oneFile);
        console.log('视频文件链接：', videoUrl);
      })
      .catch(error => {
        console.error(`加载视频 ${itemLink} 时发生错误：`, error);
      });
  });
  Promise.all(towPromises).then(async () => {
    const msg = await ffmpeg.writeFile('2025-01-23-001.mp4', await fetchFile(oneFile));
    console.log('视频写入成功', msg);
  });
}

// 处理文件上传
const handleFileUpload = (event) => {
  selectedFiles.value = Array.from(event.target.files);
  console.log('上传的视频文件:', selectedFiles.value);
  statusCode.value = 0;
  outputUrl.value = ''; // 清除之前的输出
};

// 生成黑屏视频（10秒）
const generateBlackScreen = async () => {
  try {
    // 执行 FFmpeg 命令生成黑屏视频
    await ffmpeg.exec(['-f', 'lavfi', '-t', '10', '-i', 'color=c=black:s=1920x1080:r=30', 'black.mp4']);
    // 读取生成的黑屏视频
    const data = await ffmpeg.readFile('black.mp4');
    const blackBlob = new Blob([data.buffer], { type: 'video/mp4' });
    const blackFile = new File([blackBlob], 'black.mp4', { type: 'video/mp4' });

    // 将黑屏视频添加到视频文件列表
    selectedFiles.value.push(blackFile);
    console.log('生成的黑屏视频:', blackFile);
  } catch (error) {
    console.error('生成黑屏视频时发生错误:', error);
  }
};



[
  {
    '1': '1.mp4',
    '2': '2.mp4',
    '3': 'xxx',
    '4': '3.mp4',
    '5': 'xxx',
    '6': 'xxx',
    '7': '4.mp4',
    '8': '5.mp4',
    '9': '6.mp4',
    '10': '7.mp4'
  }
]

const mp4Files = {
  '1': '1.mp4',
  '2': '2.mp4',
  '4': '3.mp4',
  '7': '4.mp4',
  '8': '5.mp4',
  '9': '6.mp4',
  '10': '7.mp4'
};
function mergeAdjacent (mp4Files) {
  const keys = Object.keys(mp4Files).map(Number); // 转换为数字数组
  const result = [];
  function recurse (i) {
    if (i >= keys.length) return;
    const currentKey = keys[i];
    const currentValue = mp4Files[currentKey];
    // 如果下一个key和当前key相差1，合并它们
    if (i + 1 < keys.length && keys[i + 1] === currentKey + 1) {
      result.push(currentValue + ' + ' + mp4Files[keys[i + 1]]);
      recurse(i + 2); // 跳过下一个元素，已合并
    } else {
      result.push(currentValue);
      recurse(i + 1);
    }
  }
  recurse(0);
  return result;
}

['1.mp4 + 2.mp4', '3.mp4', '4.mp4 + 5.mp4', '6.mp4 + 7.mp4']

// 合并视频
const mergeVideos = async () => {
  if (!isLoaded.value || selectedFiles.value.length === 0) return;
  try {
    isProcessing.value = true;
    progress.value = 0;
    statusCode.value = 1; // 更新为视频处理状态
    // 生成黑屏视频并加入到 selectedFiles 中
    // await generateBlackScreen(); // 确保黑屏视频生成完成
    // 创建文件列表文本
    let fileList = '';
    for (let i = 0; i < selectedFiles.value.length; i++) {
      const file = selectedFiles.value[i];
      const fileName = `input${i}.mp4`;
      fileList += `file ${fileName}\n`;
      // 写入文件到 FFmpeg 虚拟文件系统
      await ffmpeg.writeFile(fileName, await fetchFile(file));
    }
    // 写入文件列表
    await ffmpeg.writeFile('filelist.txt', fileList);
    // 设置进度回调
    ffmpeg.on('progress', ({ progress: p }) => {
      progress.value = Math.round(p * 100);
    });
    // 执行合并命令
    await ffmpeg.exec(['-f', 'concat', '-safe', '0', '-i', 'filelist.txt', '-c', 'copy', 'output.mp4']);
    // 读取输出文件
    const data = await ffmpeg.readFile('output.mp4');
    const blob = new Blob([data], { type: 'video/mp4' });
    outputUrl.value = URL.createObjectURL(blob);
    statusCode.value = 2; // 更新为视频播放状态
  } catch (error) {
    console.error('Error merging videos:', error);
    alert('Error merging videos. Please try again.');
  } finally {
    isProcessing.value = false;
  }
};

// 组件挂载时加载 FFmpeg
onMounted(() => { load(); });
</script>

<style scoped>
.video-merger {
  padding: 20px;
}

.upload-section {
  margin-bottom: 20px;
}

.selected-files {
  margin-top: 10px;
}

.progress {
  margin: 20px 0;
}

button {
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.output {
  margin-top: 20px;
}

video {
  max-width: 100%;
  margin: 10px 0;
}

a {
  display: inline-block;
  padding: 10px 20px;
  background-color: #2196F3;
  color: white;
  text-decoration: none;
  border-radius: 4px;
}
</style>
